package com.dating.core.auth;

import java.util.List;

import javax.servlet.http.HttpSession;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.nutz.dao.Cnd;
import org.nutz.mvc.Mvcs;

import com.dating.base.bean.User;
import com.dating.base.dao.UserDao;
import com.dating.base.service.ShiroUserService;

public class DatingAuthRealm extends AuthorizingRealm {

	
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(
			PrincipalCollection principals) {
		HttpSession session = Mvcs.getReq().getSession();
		UserDao dao = Mvcs.getIoc().get(UserDao.class);
		User user = dao.findByCondition(Cnd.where("name", "=", principals.getPrimaryPrincipal()));
		
		if(user == null){
			return null;
		}
		
		if(!user.isAvailable()){
			throw new LockedAccountException("Account [" + principals.getPrimaryPrincipal() + "] is locked.");
		}
		
		SimpleAuthorizationInfo auth = new SimpleAuthorizationInfo();
		List<String> roles = getUserService().findRolesInfo(user.getId(), user.getUserType()) ;
		List<String> permissions = getUserService().findAllPermissionsInfo(user.getId(), user.getUserType());
		auth.addRoles(roles);
		auth.addStringPermissions(permissions);
		session.setAttribute("roles", roles);
		session.setAttribute("permissions", permissions);
		return auth;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken token) throws AuthenticationException {
		UsernamePasswordToken upToken = (UsernamePasswordToken) token;
		HttpSession session = Mvcs.getReq().getSession();
		UserDao dao = Mvcs.getIoc().get(UserDao.class);
		User user = dao.findByCondition(Cnd.where("name", "=", upToken.getUsername()));
		
		if(user == null){
			return null;
		}
		
		if(!user.isAvailable()){
			throw new LockedAccountException("Account [" + upToken.getUsername() + "] is locked.");
		}
		
		SimpleAuthenticationInfo account = new SimpleAuthenticationInfo(
				user.getName(), user.getPassword(), getName());
		account.setCredentialsSalt(ByteSource.Util.bytes(upToken.getUsername()));
		session.setAttribute("roles", getUserService().findRolesInfo(user.getId(), user.getUserType()));
		session.setAttribute("permissions", getUserService().findAllPermissionsInfo(user.getId(), user.getUserType()));
		return account;
	}
	
	private ShiroUserService getUserService() {
		return Mvcs.getIoc().get(ShiroUserService.class, "shiroUserService");
	}
}
